package com.lx.inter.query;

import com.lx.wrapper.AbstractWrapper;
import com.lx.wrapper.every.LambdaGenericJoinWrapper;

import java.util.List;

/**
 * H/SQL查询结果转换器
 *
 * @author lx
 * @create 2023/2/25 16:47
 **/
public interface ResultConvertFunction<Wrapper extends AbstractWrapper<?, Wrapper>> {

    /**
     * 设置期望转换类
     *
     * @param convertClass
     * @return
     */
    Wrapper setConvertClass(Class<?> convertClass);

    /**
     * 获取期望转换类
     *
     * @return
     */
    Class<?> getConvertClass();

    /**
     * 根据结果类转换结果,获取转换结果类的选择范围优先级为 = 优先选择 [resultClass],最后使用 [entityClass]
     * 方法详情注释请参考 {@link LambdaGenericJoinWrapper#convertToResponse(Class, Object)}
     *
     * @param hibernateRes Hibernate结果,由于Hibernate特性,仅支持传入对象数组(Object[])类型
     * @param <Response>
     * @return
     */
    public default <Response> Response convertToResponse(Object hibernateRes) {
        Class<Response> resultClass = (Class<Response>) getConvertClass();
        return convertToResponse(resultClass, hibernateRes);
    }

    /**
     * 根据传入的结果类类型转换为对应的结果对象,如无法找到,则属性则为默认值
     * 注意:
     * 1.如SQL语句查出结果转换为HQL对象,则会丢失部分JoinColumn序列值.
     * 2.必须保证结果类存在默认无参构造方法
     *
     * @param resultClass
     * @param hibernateRes Hibernate结果,由于Hibernate特性,仅支持传入对象数组(Object[])类型
     * @param <Response>
     * @return
     */
    public <Response> Response convertToResponse(Class<Response> resultClass, Object hibernateRes);

    /**
     * 根据传入的结果对象进行属性赋值,如无法找到,则属性则为默认值
     * 注意:
     * 1.如SQL语句查出结果转换为HQL对象,则会丢失部分JoinColumn序列值.
     *
     * @param response
     * @param hibernateRes Hibernate结果,由于Hibernate特性,仅支持传入对象数组(Object[])类型
     * @param <Response>
     * @return
     */
    public <Response> Response convertToResponse(Response response, Object hibernateRes);

    /**
     * 根据结果类转换结果列表,获取转换结果类的选择范围优先级为 = 优先选择 [resultClass],最后使用 [entityClass]
     * 方法详情注释请参考 {@link LambdaGenericJoinWrapper#convertToResponseList(List, Class)}
     *
     * @param hibernateResList
     * @param <Response>
     * @return
     */
    public default <Response> List<Response> convertToResponseList(List<Object> hibernateResList) {
        Class<Response> entityClass = (Class<Response>) getConvertClass();
        return convertToResponseList(hibernateResList, entityClass);
    }

    /**
     * 根据传入的结果类类型转换为对应的结果对象列表,如无法找到,则属性则为默认值
     * 注意:
     * 1.如SQL语句查出结果转换为HQL对象,则会丢失部分JoinColumn序列值.
     * 2.必须保证结果类存在默认无参构造方法
     *
     * @param hibernateResList
     * @param resultClass
     * @param <Response>
     * @return
     */
    public <Response> List<Response> convertToResponseList(List<Object> hibernateResList, final Class<Response> resultClass);
}
